package adminorg;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.TreeMap;

import com.invient.vaadin.charts.InvientCharts;
import com.invient.vaadin.charts.InvientCharts.DecimalPoint;
import com.invient.vaadin.charts.InvientCharts.Series;
import com.invient.vaadin.charts.InvientCharts.SeriesType;
import com.invient.vaadin.charts.InvientCharts.XYSeries;
import com.invient.vaadin.charts.InvientChartsConfig;
import com.invient.vaadin.charts.InvientChartsConfig.AxisBase.AxisTitle;
import com.invient.vaadin.charts.InvientChartsConfig.AxisBase.NumberPlotLine;
import com.invient.vaadin.charts.InvientChartsConfig.AxisBase.NumberPlotLine.NumberValue;
import com.invient.vaadin.charts.InvientChartsConfig.CategoryAxis;
import com.invient.vaadin.charts.InvientChartsConfig.GeneralChartConfig.Margin;
import com.invient.vaadin.charts.InvientChartsConfig.HorzAlign;
import com.invient.vaadin.charts.InvientChartsConfig.Legend;
import com.invient.vaadin.charts.InvientChartsConfig.Legend.Layout;
import com.invient.vaadin.charts.InvientChartsConfig.LineConfig;
import com.invient.vaadin.charts.InvientChartsConfig.NumberYAxis;
import com.invient.vaadin.charts.InvientChartsConfig.Position;
import com.invient.vaadin.charts.InvientChartsConfig.VertAlign;
import com.invient.vaadin.charts.InvientChartsConfig.XAxis;
import com.invient.vaadin.charts.Color;
import com.invient.vaadin.charts.Color.RGB;
import com.invient.vaadin.charts.Color.RGBA;
import com.invient.vaadin.charts.InvientChartsConfig.YAxis;
import com.vaadin.ui.VerticalLayout;

public class PaintStatisticChart extends VerticalLayout {
	/**
	 * 
	 */
	private static final long serialVersionUID = 5998063503161164451L;
	private Object statUseId = null;
	private PeriodHelper PHelp = null;
	private DatabaseHelper dbHelp = null;
	private StatisticDataHelper SDHelp = null;
	
	
	public PaintStatisticChart(DatabaseHelper dbHelper, Object statUseId, Date LastDate, PeriodHelper PHelp) throws Exception{
		this();
		this.dbHelp = dbHelper;
		this.SDHelp = new StatisticDataHelper(dbHelper);
		this.PHelp = PHelp;
		this.statUseId = statUseId;
		String PT = new String(dbHelp.views.getStatisticContainer().getContainerProperty(this.statUseId,
				"aperiodprops.type").getValue().toString());
		SimpleDateFormat df =
			    new SimpleDateFormat("dd.MM.yyyy");
        CategoryAxis categoryAxis = new CategoryAxis();
        String[] Series;
        double[] Values;
        if (PT.equals("DAILY")){
			TreeMap<Integer,Date> DateValues = new TreeMap<Integer,Date>();
			DateValues = this.PHelp.getLastPeriodsD(LastDate);
			Series = new String[DateValues.size()];
			Values = new double[DateValues.size()];
			int k=0;
			for (int i=(this.PHelp.getStatQuant()-DateValues.size()+1);i<=this.PHelp.getStatQuant();i++){
				Series[k]=new String(df.format(DateValues.get(i)));
				Values[k]=new Double(this.SDHelp.getDataD(DateValues.get(i), this.statUseId));
				k++;
			}
		} else {
			TreeMap<Integer,Period> PeriodValues = new TreeMap<Integer,Period>();
			PeriodValues = PHelp.getLastPeriods(LastDate);
			Series = new String[PeriodValues.size()];
			Values = new double[PeriodValues.size()];
			int k=0;
			for (int i=(this.PHelp.getStatQuant()-PeriodValues.size()+1);i<=this.PHelp.getStatQuant();i++){
				if (this.PHelp.getPeriodView()){
					Series[k] = new String(PeriodValues.get(i).getStringValue());
					Values[k] = new Double(this.SDHelp.getDataD(PeriodValues.get(i).getStartDate(), this.statUseId));
								
				} else {
					Series[k] = new String(String.valueOf(PeriodValues.get(i).getNumber()));
					Values[k] = new Double(this.SDHelp.getDataD(PeriodValues.get(i).getStartDate(), this.statUseId));
				}
				k++;
			}
		}
		InvientChartsConfig chartConfig = new InvientChartsConfig();
        chartConfig.getGeneralChartConfig().setType(SeriesType.LINE);
        chartConfig.getGeneralChartConfig().setMargin(new Margin());
        chartConfig.getGeneralChartConfig().getMargin().setRight(130);
        chartConfig.getGeneralChartConfig().getMargin().setBottom(25);

        chartConfig.getTitle().setX(-20);
        chartConfig.getTitle().setText(dbHelp.views.getStatisticContainer().getContainerProperty(statUseId, 
				"dictstatistic.name").getValue().toString());
        chartConfig.getTitle().setX(-20);
        
        categoryAxis.setCategories(Arrays.asList(Series));
        LinkedHashSet<XAxis> xAxesSet = new LinkedHashSet<InvientChartsConfig.XAxis>();
        xAxesSet.add(categoryAxis);
        chartConfig.setXAxes(xAxesSet);

        NumberYAxis numberYAxis = new NumberYAxis();
        numberYAxis.setTitle(new AxisTitle(dbHelp.views.getStatisticContainer().getContainerProperty(statUseId, 
				"dictstatistic.code").getValue().toString()));
        NumberPlotLine plotLine = new NumberPlotLine(dbHelp.views.getStatisticContainer().getContainerProperty(statUseId, 
				"dictstatistic.code").getValue().toString());
        plotLine.setValue(new NumberValue(0.0));
        plotLine.setWidth(1);
        plotLine.setZIndex(1);
        plotLine.setColor(new RGB(128, 128, 128));
        numberYAxis.addPlotLine(plotLine);
        LinkedHashSet<YAxis> yAxesSet = new LinkedHashSet<InvientChartsConfig.YAxis>();
        yAxesSet.add(numberYAxis);
        chartConfig.setYAxes(yAxesSet);

        Legend legend = new Legend();
        legend.setLayout(Layout.VERTICAL);
        Position legendPos = new Position();
        legendPos.setAlign(HorzAlign.RIGHT);
        legendPos.setVertAlign(VertAlign.TOP);
        legendPos.setX(-10);
        legendPos.setY(100);
        legend.setPosition(legendPos);
        legend.setBorderWidth(0);
        chartConfig.setLegend(legend);

        // Series data label formatter
        LineConfig lineCfg = new LineConfig();
        chartConfig.addSeriesConfig(lineCfg);
        // Tooltip formatter
        chartConfig
                .getTooltip()
                .setFormatterJsFunc(
                        "function() { "
                                + " return '<b>' + this.series.name + '</b><br/>' +  this.x + ': '+ this.y"
                                + "}");

        InvientCharts chart = new InvientCharts(chartConfig);

        XYSeries seriesData = new XYSeries(dbHelp.views.getStatisticContainer().getContainerProperty(statUseId, 
				"dictstatistic.code").getValue().toString());
        seriesData.setSeriesPoints(getPoints(seriesData,Values));
        chart.addSeries(seriesData);

        chart.addSeries(seriesData);
        chart.setSizeFull();
        chart.setImmediate(true);
        this.addComponent(chart);
	}
	
    public PaintStatisticChart() {
		// TODO Auto-generated constructor stub
	}

	private static LinkedHashSet<DecimalPoint> getPoints(Series series,
            double... values) {
        LinkedHashSet<DecimalPoint> points = new LinkedHashSet<DecimalPoint>();
        for (double value : values) {
            points.add(new DecimalPoint(series, value));
        }
        return points;
    }
	
	private static LinkedHashSet<DecimalPoint> getPoints(Series series,
	            double[]... values) {
	        LinkedHashSet<DecimalPoint> points = new LinkedHashSet<DecimalPoint>();
	        for (double[] value : values) {
	            Double x, y = null;
	            if (value.length == 0)
	                continue;
	            if (value.length == 2) {
	                x = value[0];
	                y = value[1];
	            } else {
	                x = value[0];
	            }
	            points.add(new DecimalPoint(series, x, y));
	        }
	        return points;
	    }

	    private static String getFormattedTimestamp(Date dt) {
	        if (dt == null) {
	            return null;
	        }
	        SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd hh:mm:ss");
	        return format.format(dt);
	    }

}
